package com.itheima.reggie.commons;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.reggie.pojo.Page;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Set;

@Slf4j
@Aspect
@Component
public class ReggieAdvice {
    @Autowired
    private HttpSession session;

    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 对持久层的save方法增强
     */
    @SneakyThrows
    @Before("execution(* com.itheima.reggie.dao.*Dao.save*(*))")
    public void beforeSave(JoinPoint joinPoint) {
        //1. 得到方法的参数数组
        Object[] args = joinPoint.getArgs();
        //2. 获取第1个参数，如：employee对象
        Object entity = args[0];
        //3. 获取参数的类对象
        Class<?> entityClass = entity.getClass();
        //4. 从会话域中获取employee的id
        Long loginId = (Long) session.getAttribute("LOGIN_ID");
        //5. 获取set方法赋值
        Method setCreateUser = entityClass.getMethod("setCreateUser", Long.class);
        //5.1. 设置添加者id的属性
        setCreateUser.invoke(entity, loginId);
        //5.2. 设置更新者的id属性
        Method setUpdateUser = entityClass.getMethod("setUpdateUser", Long.class);
        setUpdateUser.invoke(entity, loginId);
        //5.3. 设置创建的时间
        Method setCreateTime = entityClass.getMethod("setCreateTime", LocalDateTime.class);
        setCreateTime.invoke(entity, LocalDateTime.now());
        //5.4. 设置更新的时间
        Method setUpdateTime = entityClass.getMethod("setUpdateTime", LocalDateTime.class);
        setUpdateTime.invoke(entity, LocalDateTime.now());
        //6. 输出日志信息
        log.info("添加前设置实体类的属性值：{}", entity);
    }

    /**
     * 对持久层的update方法增强
     */
    @SneakyThrows
    @Before("execution(* com.itheima.reggie.dao.*Dao.update*(*))")
    public void beforeUpdate(JoinPoint joinPoint) {
        //得到方法的参数数组
        Object[] args = joinPoint.getArgs();
        //获取第1个参数，如：employee对象
        Object entity = args[0];
        //获取参数的类对象
        Class entityClass = entity.getClass();
        //从会话域中获取employee的id
        Long loginId = (Long) session.getAttribute("LOGIN_ID");

        //设置更新者的id属性
        Method setUpdateUser = entityClass.getMethod("setUpdateUser", Long.class);
        setUpdateUser.invoke(entity, loginId);

        //设置更新的时间
        Method setUpdateTime = entityClass.getMethod("setUpdateTime", LocalDateTime.class);
        setUpdateTime.invoke(entity, LocalDateTime.now());

        //输出日志
        log.info("修改前设置实体类的属性值：{}", entity);
    }

    /**
     * 分页
     * @param joinPoint
     * @return
     */
    @SneakyThrows
    @Around("execution(* com.itheima.reggie.service.*Service.findByPage(..))")
    public Page handlePage(ProceedingJoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        Integer pageNum = (Integer) args[0];
        Integer pageSize = (Integer) args[1];
        log.info("分页增强");
        //1.设置页码和页面大小(生成2条SQL语句)
        PageHelper.startPage(pageNum, pageSize);
        Page page = (Page) joinPoint.proceed();
        PageInfo pageInfo = new PageInfo<>(page.getRecords());
        return new Page(pageInfo.getList(),pageInfo.getTotal(),pageSize,pageNum);
    }

    @SneakyThrows
    @AfterReturning("@annotation(com.itheima.reggie.annotation.DeleteCahe)")
    public void cleanDishRedis(){
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        log.info("清除菜品缓存成功");
    }
}
